from django.shortcuts import render
from django.views import View
from django.contrib.auth import authenticate, login, logout  # 用于验证用户
from django.http import HttpResponseRedirect, JsonResponse
from django.urls import reverse
import redis

from .forms import LoginForm, DynamicLoginForm, DynamicLoginPostForm, RegisterGetForm, RegisterPostForm  # 用于表单验证
from .models import UserProfile
from MxOnline.settings import REDIS_HOST, REDIS_PORT

from utils.HuYi import send_single_sms
from utils.random_sty import generate_random


# 注销方法
class LogoutView(View):
    # get 请求
    def get(self, request, *args, **kwargs):
        logout(request)
        return HttpResponseRedirect(reverse('login'))  # 注销后跳转登录页面


# 登录方法
class LoginView(View):
    # get 请求
    def get(self, request, *args, **kwargs):  # *args, **kwargs 是为了方便的动态传入不同个数、不同类型的参数
        # 跳转登录页面时判断用户是否登录，登录了就前往首页
        if request.user.is_authenticated:
            return HttpResponseRedirect(reverse('index'))

        login_form = DynamicLoginForm()
        return render(request, 'login.html', {'login_form': login_form})

    # post 请求
    def post(self, request, *args, **kwargs):

        login_form = LoginForm(request.POST)
        # 表单验证（需要新建 forms.py）文件
        if login_form.is_valid():

            user_name = login_form.cleaned_data['username']
            password = login_form.cleaned_data['password']

            # username = request.POST.get('username', '')  # 取不到就默认为空
            # password = request.POST.get('password', '')  # 取不到就默认为空

            # if not user_name:
            #     return render(request, 'login.html', {'msg': '请输入用户名！'})
            # if not password:
            #     return render(request, 'login.html', {'msg': '请输入密码！'})

            # 查询用户
            user = authenticate(username=user_name, password=password)
            if user is not None:
                # 查询到用户
                login(request, user)  # 登录用户
                # 登录成功后应该怎样返回页面
                return HttpResponseRedirect(reverse('index'))
            else:
                # 未查询到用户
                return render(request, 'login.html', {'msg': '用户名或密码错误！', 'login_form': login_form})
        else:
            return render(request, 'login.html', {'login_form': login_form})


# 注册视图
class RegisterView(View):
    def get(self, request, *args, **kwargs):
        register_get_form = RegisterGetForm()
        return render(request, 'register.html', {'register_get_form': register_get_form})

    def post(self, request, *args, **kwargs):
        register_post_form = RegisterPostForm(request.POST)
        if register_post_form.is_valid():  # 需要在form.py 中自定义验证，验证用户输入的手机号是否注册
            # 验证通过后, 取得用户提交的：手机号码、密码
            mobile = register_post_form.cleaned_data['mobile']
            password = register_post_form.cleaned_data['password']
            # 新建用户
            user = UserProfile(username=mobile, mobile=mobile)
            user.set_password(password)  # 加密密码
            user.save()
            login(request, user)  # 最后进行用户登录
            return HttpResponseRedirect(reverse('index'))  # 前往首页
        else:
            register_get_form = RegisterGetForm()  # 图片验证码表单
            # 注册验证不通过，返回登录页，将图片验证码表单与注册表单返回
            return render(request, 'register.html',
                          {'register_post_form': register_post_form, 'register_get_form': register_get_form})


# 图片验证码验证，当用户点击发送手机验证码时触发
class SendSmsView(View):
    def post(self, request, *args, **kwargs):
        send_sms_form = DynamicLoginForm(request.POST)
        res_dick = {}  # 保存前端的响应数据

        if send_sms_form.is_valid():
            mobile = send_sms_form.cleaned_data['mobile']
            is_register = request.POST['isRegister']  # 判断是否是注册操作

            # 随机生成手机短信验证码
            code = generate_random(4, 0)
            res_json = send_single_sms('C71428053', '3c121830cd08eec4c7148a55e55b7b91', code, mobile)  # 发送短信后的响应代码
            # res_json = {'code': 2, 'msg': '提交成功', 'smsid': '16111063741348220753'}

            # 判断是否是注册操作并判断手机号是否注册，为真的话抛出错误提示给前端
            if is_register == 'True' and UserProfile.objects.filter(mobile=mobile):  # 查询用户是否存在
                res_dick['msg'] = '该手机号码已经被注册！请登录'

            elif res_json['code'] == 2:
                res_dick['status'] = 'success'

                # 保存手机验证码到 redis 服务器
                r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0, decode_responses=True)
                r.set(str(mobile), code)
                r.expire(str(mobile), 60 * 5)  # 设置验证码5分钟过期
                print('手机验证码发送成功')
            else:
                res_dick['msg'] = res_json['msg']
                print('手机验证码发送失败')
        else:
            for key, value in send_sms_form.errors.items():
                res_dick[key] = value[0]
            print('验证不通过')
        return JsonResponse(res_dick)


# 手机验证码验证，动态登录时，当用户输入手机验证码并点击登录按钮时触发该视图
class DynamicLoginView(View):
    def post(self, request, *args, **kwargs):
        login_form = DynamicLoginPostForm(request.POST)
        dynamic_login = True  # 控制是否是动态登录, 走这个视图必然是动态登录

        if login_form.is_valid():  # 自带的验证只验证了mobile、code的长度与值是否不为空，需要在form.py 中自定义验证，验证用户输入的code是否与数据库的相同
            # 手机验证码验证通过后，没有账户也可以登录
            mobile = login_form.cleaned_data['mobile']
            existed_users = UserProfile.objects.filter(mobile=mobile)  # 查询用户是否存在
            if existed_users:
                user = existed_users[0]
            else:
                # 新建用户，必填：用户名、密码、手机号码
                user = UserProfile(username=mobile, mobile=mobile)
                password = generate_random(10, 2)  # 随机 生成密码
                user.set_password(password)  # 加密密码
                user.save()
            login(request, user)  # 最后进行用户登录
            return HttpResponseRedirect(reverse('index'))  # 前往首页
        else:
            d_form = DynamicLoginForm()  # 图片验证码表单
            # 手机验证码验证不通过，返回登录页
            return render(request, 'login.html',
                          {'login_form': login_form, 'dynamic_login': dynamic_login, 'd_form': d_form})
